import sys, commands, math

def main():
  rating = generateRatings()
  movies = getAllMovies(rating) #Genera todas las peliculas
  categories = getAllCategories() #Genera todas las categorias
  data = generateDataGraph(rating)
"""  
  print "IMRPIMO"
  max_c = 0
  t = ('','')
  for x in data:
    if data[x].items():
      print movies[x]['title'] + '(' + str(getMovieRating(x, rating))[:5] + '):'
      for v,k in data[x].items():
        print '\t',movies[v]['title'] + '\t' + str(k)[:5], str(getMovieRating(v, rating))[:5]
        if max_c < k:
          max_c = k
          t = (x,v)
"""

def generateRatings():
  """Devuelve un diccionario de <pelicula, {'starts', 'votes'}>
  ademas de una entrada 'avg' que sirve para acelerar
  los calculos"""
  f = open("../data/100mil/u.data", "rU")
  str = f.read()
  f.close()
  str = str.splitlines()
  rating = {}
  for item in str:
    aux = item.split('\t')
    movie, rank = int(aux[1]), int(aux[2])
    if not movie in rating:
      rating[movie] = {'stars': 0, 'votes': 0}
    rating[movie]['stars'] = rating[movie]['stars']  + rank
    rating[movie]['votes'] = rating[movie]['votes']  + 1
  
  avg_votes = 0
  avg_stars = 0
  for m in rating:
    avg_votes =  avg_votes + rating[m]['votes']
    avg_stars = avg_stars + rating[m]['stars']/float(rating[m]['votes'])
  avg_votes = avg_votes / float(len(rating))
  avg_stars = avg_stars / float(len(rating))
  rating['avg'] = {'votes': avg_votes, 'stars': avg_stars}
  return rating

def getMovieRating(movie, rating):
  """Devuelve el promedio bayesiano de una
  pelicula basado en el rating"""
  return (rating['avg']['votes'] * rating['avg']['stars'] + rating[movie]['stars']) / \
            (rating['avg']['votes'] + rating[movie]['votes'])
  
def getAllMovies(rating):
  """Devuelve un diccionario <pelicula, {titulo, imdb, categorias, ratring}>
    categorias es un conunto de ids de categorias"""
  f = open("../data/100mil/u.item", "rU")
  str = f.read()
  f.close()
  str = str.splitlines()
  #GENERATE THE MOVIES
  movies = {}
  for item in str:
    aux = item.split("|")
    m = int(aux[0])
    movies[m] = {'title': aux[1], 'imdb': aux[4], 'categories': getCategorySet(aux[-19:]), \
        'rating': getMovieRating(m, rating) }
  return movies

def getAllCategories():
  """Devuelve un diccionario <id, categoria>"""
  f = open("../data/100mil/u.genre", "rU")
  str = f.read()
  f.close()
  str = str.splitlines()
  categories = {}
  for item in str:
    aux = item.split("|")
    categories[int(aux[1])] = aux[0]
  return categories

def generateDataGraph(rating):
  f = open("../data/100mil/u.data", "rU")
  str = f.read()
  f.close()
  str = str.splitlines()
  user_vote = {}
  for item in str[:30000]:
    aux = item.split('\t')
    user, movie, rank = int(aux[0]), int(aux[1]), int(aux[2])
    if not user in user_vote:
      user_vote[user] = {}
    user_vote[user][movie] = rank
  
  data = {}
  """TODO ME QUEDE ACA  """
  for votes in user_vote:
    for movie in user_vote[votes]:
      if not movie in data:
        data[movie] = {}
      for movie2 in set([i for i in user_vote[votes] if movie < i]):
        if not movie2 in data:
          data[movie2] = {}
        if not movie2 in data[movie]:
          data[movie][movie2] = [0,0]
        if not movie in data[movie2]:
          data[movie2][movie] = [0,0]
        data[movie][movie2][1] = data[movie][movie2][1] + 1
        data[movie2][movie][1] = data[movie2][movie][1] + 1
        if user_vote[votes][movie] > 3 and user_vote[votes][movie2] > 3:
          data[movie][movie2][0] = data[movie][movie2][0] + 1
          data[movie2][movie][0] = data[movie2][movie][0] + 1
  
  full_data = {}
  for m1 in data:
    if not m1 in full_data:
      full_data[m1] = {}
    for m2 in data[m1]:
      if data[m1][m2][1] > 5 and data[m1][m2][0] > 0:
        #full_data[m1][m2] = math.log( (data[m1][m2][0]/float(data[m1][m2][1])) * (getMovieRating(m1, rating)*getMovieRating(m2, rating)) , 2)
        full_data[m1][m2] = (data[m1][m2][0]/float(data[m1][m2][1])) * getMovieRating(m2, rating)
          
  return full_data

def getCategorySet(categories):
  """Devuelve el un conjunto de idcategoria
  de las categorias que tiene una pelicula"""
  return set([k for k in range(len(categories)) if int(categories[k])])

def dibujar(data, movies):
    buf = []
    buf.append('graph grafo {')
    #for v in data:
    #  buf.append('%s [ label="%s" ]' % (v, movies[v]['title']) )
    for v in data:
      for w in [x for x in data[v] if x < v]:
        buf.append('"%s" -- "%s" [ label = "%s" ]' %  (movies[v]['title'], movies[w]['title'], data[v][w]) )
    buf.append('}')
    cmd = 'echo "' + '\n'.join(buf) + '" | dot -Tpng > rank.png'
    print cmd
    commands.getoutput(cmd)  

if __name__ == "__main__":
  main()
